package java_thinking.unit_15._15_3;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

/**
 * @Description :
 * @author: cww
 * @DateTime: 2019/4/1 20:43
 */

public class Coffee {
    private static long counter = 0;
    private final long id = counter++;
    @Override
    public String toString() {
        return getClass().getSimpleName() +" "+id;
    }
}

class Latte extends Coffee {}
class Mocha extends Coffee {}
class Cappuccino extends Coffee {}
class Breve extends Coffee {}
class Americano extends Coffee {}

/**
 * 这个例子之所以要继承Iterable，就是为了实现Iterator对象，可以用来foreach
 * Generator的next()与Iterator中的next()功能其实是一样的，所以直接在内部类中引用外围类的next()方法了
 *
 * 参数化的Generator接口确保next()的返回值是参数的类型
 */
class CoffeeGenerator implements Generator<Coffee>,Iterable<Coffee> {
    private Class[] types = {Latte.class,Mocha.class,Cappuccino.class,Breve.class,Americano.class};
    private Random random = new Random(47);
    public CoffeeGenerator() {
    }
    private int size = 0;
    public CoffeeGenerator(int size) {
        this.size = size;
    }

    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    @Override
    public Iterator<Coffee> iterator() {
        return new CoffeeIterator();
    }

    @Override
    public Coffee next() {
        try {
            return (Coffee) types[random.nextInt(types.length)].newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    class CoffeeIterator implements Iterator<Coffee> {
        private int count = size;

        @Override
        public boolean hasNext() {
            return count>0;
        }


        @Override
        public Coffee next() {
            count--;
            /**
             * 这里要返回的是外围类的next(),如果这里直接用this.next()则返回的是内部类自己的next()
             * 内部类访问外部类:(外部类.this.变量)
             */
            return CoffeeGenerator.this.next();
        }

    }

    public static void main(String[] args) {
        CoffeeGenerator coffees = new CoffeeGenerator();
        for (int i = 0; i<5;i++) {
            System.out.println(coffees.next());
        }
        for (Coffee c : new CoffeeGenerator(5)){
            System.out.println(c);
        }
    }
}

class CoffeeGenerator1<T> implements Iterator<T> {

    private List<T> stringList ;
    private int count ;
    public CoffeeGenerator1(List<T> stringList){
        this.stringList = stringList;
        count = stringList.size();
    }
    @Override
    public boolean hasNext() {
        return count >0;
    }

    /**
     * Returns the next element in the iteration.
     *
     * @return the next element in the iteration
     */
    @Override
    public T next() {
        count--;
        return stringList.get(count);
    }

    public static void main(String[] args) {
        CoffeeGenerator1 coffeeGenerator1 = new CoffeeGenerator1(Arrays.asList(("Sometimes the truth may be held in a handful of persons' hands").split(" ")));
        while (coffeeGenerator1.hasNext()){
            System.out.println(coffeeGenerator1.next());
        }
        System.out.println();
        for (String s : ("Sometimes the truth may be held in a handful of persons' hands").split(" ")){
            System.out.print(s+" ");
        }

    }
}